package org.zeroes.svg;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import com.larvalabs.svgandroid.*;
import android.graphics.Path;
import android.graphics.PathMeasure;
public class SVGElement {
	
	public static final int TYPE_IMAGE = 0; 
	public static final int TYPE_LAYER = 1; 
	public static final int TYPE_GROUP = 2; 
	public static final int TYPE_FREE_IMAGE = 3; 
	public static final int TYPE_GROUPED_IMAGE = 4; 
	public static final int TYPE_BATCH_LAYER = 5; 
	public static final int TYPE_TEXTURE_ATLAS_IMAGE = 6; 
	public static final int TYPE_BATCH_LAYER_RECT = 7; 
	public static final int TYPE_TEXTURE_ATLAS_INSTANCE = 8; 
	public static final int TYPE_TEXTURE_ATLAS_GROUPEDINSTANCE = 9; 
	public int trstype=0;
	public String layerID="";
	public SVGElement linkedElem;
	public float x;
	public float y;
	public float tx;
	public float ty;
	public int z=0;
	public float opacity=1;
	
	public float rot=0;
	public float sx=1;
	public float sy=1;
	public float width;
	public float height;
	public String parentID="";
	public boolean done=false;
	public String id;
	public String pathData;
	private String customData=null;
	public int type;
	//public List<SVGElement> clones;
	public float[] td= new float[6];
	//public String rawdata;
	public byte[] imageBytes;
	
	public SVGElement(String x,String y, String _w, String _h, String _id,String _pid){
		this.x=(Float.valueOf(x).floatValue());
		this.y=(Float.valueOf(y).floatValue());
		this.id=_id;
		this.parentID=_pid;
		this.width=(Float.valueOf(_w).floatValue());
		this.height=(Float.valueOf(_h).floatValue());
		
		//clones = new ArrayList<SVGElement>();
		
	}
	
	public SVGElement(String id ,String tg,String _trs,List<SVGElement> list){
		this.id=id;
		if(!_trs.equals("")){
		if(_trs.startsWith("translate")){
			String ts = _trs.substring(10, _trs.length()-1);
			String[] items = ts.split(",");	
			this.tx=(Float.valueOf(items[0]).floatValue());
			this.ty=(Float.valueOf(items[1]).floatValue());
			trstype=1;
			
		}
		else
		{
		double[] trsf=this.parseTRS(_trs);
		this.rot=(float) trsf[0];
		this.sx=(float) trsf[1];
		this.sy=(float) trsf[2];
		this.tx= (float)trsf[4];
		this.ty= (float)trsf[5];
		}
		}
		
		if(tg.startsWith("#")){
		String target = tg.substring(1, tg.length());	
			for(SVGElement nod:list){
				if (nod.id.equals(target)){
					
					this.linkedElem=nod;
					
				}
					
				
			}
		
		}
		
	}
	public SVGElement(String id, String data){
		
		this.id=id;
		this.pathData=data;
		
	}
	
	public SVGElement(String x,String y,String id,String rd, String _trs){
		this.x=(Float.valueOf(x).floatValue());
		this.y=(Float.valueOf(y).floatValue());
		this.id=id;
		this.type=TYPE_IMAGE;
		//this.rawdata=rd;
		try {
			imageBytes=Base64.decode(rd.substring(22));
		} catch (IOException e1) {
			e1.printStackTrace();
		}
		if(!_trs.equals("")){
		if(_trs.startsWith("translate")){
			String ts = _trs.substring(10, _trs.length()-1);
			String[] items = ts.split(",");	
			this.tx=(Float.valueOf(items[0]).floatValue());
			this.ty=(Float.valueOf(items[1]).floatValue());
			trstype=1;
			
		}
		else
		{
		double[] trsf=this.parseTRS(_trs);
		this.rot=(float) trsf[0];
		this.sx=(float) trsf[1];
		this.sy=(float) trsf[2];
		this.tx=(float) trsf[4];
		this.ty= (float)trsf[5];
		}
		}
	//	clones = new ArrayList<SVGElement>();
	}
	public SVGElement(String title){
		
		this.id=title;
		this.type=TYPE_LAYER;
	//	clones = new ArrayList<SVGElement>();
	}
	public void setID(String ident){
		this.id=ident;
		
	}
	public void setTRS(String _trs){
		
		double[] trsf=this.parseTRS(_trs);
		this.rot=(float) trsf[0];
		this.sx=(float) trsf[1];
		this.sy=(float) trsf[2];
	}
	public void setZ(String zet){
		
		this.z=(int)(Float.valueOf(zet).floatValue());
	}
	public void setStyle(String s){
		
		String[] items = s.split(":");
		if(items[0].equals("opacity"))
		{
		this.opacity=Float.valueOf(items[1]).floatValue();	
		}
		
	}
	private double[] parseTRS(String s){

		String ts = s.substring(7, s.length()-1);
		String[] items = ts.split(",");
		
		this.td[0]=Float.valueOf(items[0]).floatValue();
		this.td[1]=Float.valueOf(items[1]).floatValue();
		this.td[2]=Float.valueOf(items[2]).floatValue();
		this.td[3]=Float.valueOf(items[3]).floatValue();
		this.td[4]=Float.valueOf(items[4]).floatValue();
		this.td[5]=Float.valueOf(items[5]).floatValue();
		
		double[][] row = new double[2][2];
	double tx=0,ty=0;
	tx=Float.valueOf(items[4]).floatValue();
	ty=Float.valueOf(items[5]).floatValue();
			row[0][0]=Float.valueOf(items[0]).floatValue();
			row[0][1]=Float.valueOf(items[2]).floatValue();
			row[1][0]=Float.valueOf(items[1]).floatValue();
			row[1][1]=Float.valueOf(items[3]).floatValue();
			
			double outscalex = Math.sqrt(norm(row[0]));
            normalize(row[0]);
            
           double outshear = row[0][0] * row[1][0] + row[0][1] * row[1][1];
           row[1][0]=row[1][0] - row[0][0] * outshear;
           row[1][1]=row[1][1] - row[0][1] * outshear;
           
          double outscaley = Math.sqrt(norm(row[1]));
           normalize(row[1]);
           outshear /= outscaley;

           // rotation
           double sin = -row[0][1],
               cos = row[1][1];
           double outrotate=0;
           if (cos < 0) {
               outrotate = Math.toDegrees(Math.acos(cos));
               if (sin < 0) {
                   outrotate = 360 - outrotate;
               }
           } else {
               outrotate = Math.toDegrees(Math.asin(sin));
           }

double[] out = new double[6];
out[0]=outrotate;
out[1]=outscalex;
out[2]=outscaley;
out[3]=outshear;
out[4]=tx;
out[5]=ty;
		return out;
	}
	
private double norm(double[] a){
	
	return a[0] * a[0] + a[1] * a[1];
}
private void normalize(double[] a){
	double mag = Math.sqrt(norm(a));
	a[0] /= mag;
    a[1] /= mag;
}

public static Path getPathFromString (String d){
	
	return SVGParser.parsePath(d);
}

public static float getPathLength(Path aPath){
	
	PathMeasure pm = new PathMeasure(aPath,true);
	 return pm.getLength();
}
public static float[] getPathPositionAtLength(Path p,float distance){
	
	float[] pos = new float[2];
	float[] ang = new float[2];
	PathMeasure pm = new PathMeasure(p,true);
	pm.getPosTan(distance, pos, ang);
	float[] res = {pos[0],pos[1],ang[0],ang[1]};
	return res;
}

/**
 * @return the customData
 */
public String getCustomData() {
	return customData;
}

/**
 * @param customData the customData to set
 */
public void setCustomData(String customData) {
	this.customData = customData;
}

}
